﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using Emgu.CV;
using Emgu.CV.CvEnum;
using Emgu.CV.Structure;
using Emgu.CV.Util;
using Emgu.CV.VideoSurveillance;
using Emgu.Util;
using System.Threading;
using System.Threading.Tasks;

namespace TY_Hoist.WinApp
{
    public partial class Form6 : Form
    {
        private VideoCapture _capture;
        public Form6()
        {
            InitializeComponent();
            //try to create the capture

        }

        private void Form6_Load(object sender, EventArgs e)
        {
            _capture = new VideoCapture(@"F:\燃烧\新建文件夹\CamVideo.avi");
            Work();

        }
        public void Work()
        {
            Task.Factory.StartNew(() =>
            {
                Image<Bgr, byte> lastFrame = null;
                var isFirstFrame = false;
                int j = 0;
                while (true)
                {
                    j++;
                    
                    try
                    {
                        using (Image<Bgr, byte> nextFrame = _capture.QueryFrame().ToImage<Bgr, byte>())
                        {
                            //pictureBox1.Image = nextFrame.ToBitmap();

                            if (isFirstFrame)
                            {
                                //pictureBox2.Image = lastFrame.ToBitmap();

                                Image<Bgr, byte> diffFrame = new Image<Bgr, Byte>(lastFrame.Width, lastFrame.Height);
                                
                                diffFrame = nextFrame.AbsDiff(lastFrame);
                                Image<Bgr, Byte> dest = new Image<Bgr, Byte>(lastFrame.Width, lastFrame.Height);
                                CvInvoke.Threshold(diffFrame, dest, 50, 255, ThresholdType.Binary);
                                Image<Bgr, Byte> dest1 = new Image<Bgr, Byte>(lastFrame.Width, lastFrame.Height);
                                CvInvoke.Dilate(dest, dest1, new Image<Gray, Byte>(lastFrame.Width, lastFrame.Height), new Point(-1, -1), 4, BorderType.Constant, new MCvScalar(255, 255, 255));
                                VectorOfVectorOfPoint con = new VectorOfVectorOfPoint();
                                Image<Gray, byte> c = new Image<Gray, byte>(lastFrame.Width, lastFrame.Height);
                                Image<Gray, byte> d = new Image<Gray, byte>(lastFrame.Width, lastFrame.Height);
                                Image<Gray, Byte> dest2 = new Image<Gray, Byte>(lastFrame.Width, lastFrame.Height);
                                CvInvoke.CvtColor(dest1, dest2, ColorConversion.Rgb2Gray);
                                CvInvoke.FindContours(dest2, con, c, RetrType.External, ChainApproxMethod.ChainApproxSimple);
                                UpdateText(con.Size.ToString());
                                for (int i = 0; i < con.Size; i++)
                                {
                                    CvInvoke.DrawContours(nextFrame, con, i, new MCvScalar(255, 0, 255, 255), 2);
                                }

                                //pictureBox3.Image = diffFrame.ToBitmap();
                                //CvInvoke.PutText(nextFrame, moves.ToString(), new System.Drawing.Point(20, 20), Emgu.CV.CvEnum.FontFace.HersheyPlain, 1, new MCvScalar(255, 255, 0), 1);
                                //setPictureBoxControlImage(pb, nextFrame.ToBitmap());
                                //if (moves > 20)
                                //    label1.Text = "moved!";
                                //else
                                //    label1.Text = "sleeps...";

                                this.Invoke(new Action(() =>
                                {

                                    pictureBox1.Image = nextFrame.ToBitmap();
                                }));
                            }
                            else
                            {
                                if (j == 20)
                                {
                                    lastFrame = nextFrame.Copy();
                                    isFirstFrame = true;
                                }
                            }
                        }
                    }
                    catch (Exception ex)
                    {

                        UpdateText(ex.Message);
                    }

                }


            });
     

        }

        private void UpdateText(String text)
        {
            if (!IsDisposed && !Disposing && InvokeRequired)
            {
                Invoke((Action<String>)UpdateText, text);
            }
            else
            {
                label3.Text = text;
            }
        }



        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {

            if (disposing && (components != null))
            {
                components.Dispose();
            }

            base.Dispose(disposing);
        }
    }
}
